﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SmartSpace.Core;
using SmartSapce.ServiceLocation;

namespace WorkSpace.Core
{
    public class WorkSpaceService : IWorkSpaceService
    {
        private IWorkSpaceFactory _factory;
        private ICoreService _coreService;

        public WorkSpaceService(IWorkSpaceFactory factory, ICoreService coreService)
        {
            _factory = factory;

            _coreService = coreService;
        }

        public WorkSpaceService()
        {
            _factory = new WorkSpaceFactory();

            _coreService = ServiceLocator.Get<ICoreService>();
        }

        public bool SaveCategory(Category category)
        {
            using (WorkSpaceContext context = _factory.Get())
            {
                if (context.Set<Category>()
                    .Where(p => p.Id == category.Id)
                    .Select(p => p.Id)
                    .FirstOrDefault() == default(Guid))
                {
                    context.Set<Category>().Add(category);
                }
                else
                {
                    context.Entry(category).State = System.Data.Entity.EntityState.Modified;
                }

                if (context.SaveChanges() > 0)
                {
                    return true;
                }
                return false;
            }
        }
        
        public List<Category> FindCategories()
        {
            using (WorkSpaceContext context = _factory.Get())
            {
                return context.Set<Category>().ToList();
            }
        }

        public bool SaveLink(Link link)
        {
            using (WorkSpaceContext context = _factory.Get())
            {
                link.Category = null;
                if (context.Set<Link>()
                    .Where(p => p.Id == link.Id)
                    .Select(p => p.Id)
                    .FirstOrDefault() == default(Guid))
                {
                    context.Set<Link>().Add(link);
                }
                else
                {
                    context.Entry(link).State = System.Data.Entity.EntityState.Modified;
                }

                if (context.SaveChanges() > 0)
                {
                    return true;
                }
                return false;
            }
        }
        
        public List<Link> FindLinks(Guid categoryId)
        {
            using (WorkSpaceContext context = _factory.Get())
            {
                return context.Set<Link>()
                    .Include("Category")
                    .Where(p=>p.CategoryId == categoryId)
                    .ToList();
            }
        }

        public List<Link> FindInheritedLinks(string account)
        {
            OrgMember position = _coreService.FindMajorPosition(account);

            List<Org> parents = _coreService.FindParentOrgs(position.OrgId, Guid.Empty);

            if (parents == null || parents.Count == 0)
            {
                return new List<Link>();
            }

            using (WorkSpaceContext context = _factory.Get())
            {
                StringBuilder sql = new StringBuilder();
                sql.Append(@"select wl.* from wslink as wl
	join __User as u on u.Account = wl.Account
	join __orgmember as om on om.UserId = u.Id
where om.Orgid='");

                for (int index = 0; index < parents.Count; index++)
                {
                    if (index == 0)
                    {
                        sql.Append(parents[index].Id.ToString("D"));
                    }
                    else
                    {
                        sql.AppendFormat(@",{0}", parents[index].Id.ToString("D"));
                    }
                }
                sql.Append(@"' and wl.isEnable=1");

                List<Link> links = context.Set<Link>()
                    .SqlQuery(sql.ToString()).ToList();

                for (int index = 0; index < links.Count; index++)
                {
                    Link link = links[index];
                    link.Category = context.Set<Category>().Where(p => p.Id == link.CategoryId)
                        .FirstOrDefault();
                }

                return links;
            }
        }

        /// <summary>
        /// 获取自己创建的连接
        /// </summary>
        /// <param name="account"></param>
        /// <returns></returns>
        public List<Link> FindPrivateLinks(Guid categoryId, string account)
        {
            using (WorkSpaceContext context = _factory.Get())
            {
                if (categoryId == Guid.Empty)
                {
                    return context.Set<Link>()
                        .Include("Category")
                        .Where(p => p.Account == account)
                        .ToList();
                }
                else
                {
                    return context.Set<Link>()
                        .Include("Category")
                        .Where(p => p.Account == account && p.CategoryId == categoryId)
                        .OrderBy(p => p.OrderIndex)
                        .ToList();
                }
            }
        }

        public List<Link> FindAllLinks(string account)
        {
            List<Link> links = new List<Link>();
            links.AddRange(FindPrivateLinks(Guid.Empty, account));
            links.AddRange(FindInheritedLinks(account));
            return links;
        }

        /// <summary>可以用的链接
        /// 获取该类别所有
        /// </summary>
        /// <param name="categoryId"></param>
        /// <param name="account"></param>
        /// <returns></returns>
        public List<Link> FindAllLinks(Guid categoryId, string account)
        {
            List<Link> links = new List<Link>();
            links.AddRange(FindPrivateLinks(Guid.Empty, account));
            links.AddRange(FindInheritedLinks(account));
            for (int index = 0; index < links.Count;)
            {
                if (links[index].CategoryId == categoryId)
                {
                    index++;
                }
                else
                {
                    links.RemoveAt(index);
                }
                
            }
            return links;
        }

        public Link FindLink(Guid linkId)
        {
            using (WorkSpaceContext context = _factory.Get())
            {
                return context.Set<Link>()
                    .Include("Category")
                    .Where(p => p.Id == linkId)
                    .FirstOrDefault();
            }
        }

        public List<Category> FindCategories(string account)
        {
            using (WorkSpaceContext context = _factory.Get())
            {
                return context.Set<Category>()
                    .Where(p=>p.Account == account)
                    .OrderBy(p=>p.OrderIndex)
                    .ToList();
            }
        }

        public bool SavePersonalPackage(PersonalPackage package)
        {
            using (WorkSpaceContext context = _factory.Get())
            {
                if (context.Set<PersonalPackage>()
                    .Where(p => p.Id == package.Id)
                    .Select(p => p.Id)
                    .FirstOrDefault() == default(Guid))
                {
                    context.Set<PersonalPackage>().Add(package);
                }
                else
                {
                    context.Entry(package).State = System.Data.Entity.EntityState.Modified;
                }

                if (context.SaveChanges() > 0)
                {
                    return true;
                }
                return false;
            }
        }

        public bool RemovePersonalPackage(Guid packageId)
        {
            using (WorkSpaceContext context = _factory.Get())
            {
                PersonalPackage package = context.Set<PersonalPackage>()
                    .Where(p => p.Id == packageId)
                    .FirstOrDefault();
                if (package!= null)
                {
                    //context.Entry(package).State = System.Data.Entity.EntityState.Deleted;
                    context.Set<PersonalPackage>().Remove(package);
                    if (context.SaveChanges() > 0)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                return true;
            }
        }
        
        public bool AddPersonalLink(PersonalPackage package, Guid linkId)
        {
            using (WorkSpaceContext context = _factory.Get())
            {
                if (context.Set<PersonalLink>()
                    .Where(p => p.LinkId == linkId && p.PackageId == package.Id)
                    .Select(p => p.Id)
                    .FirstOrDefault() == default(Guid))
                {
                    PersonalLink link = new PersonalLink();
                    link.Id = Guid.NewGuid();
                    link.LinkId = linkId;
                    link.PackageId = package.Id;
                    link.Account = package.Account;
                    link.IsDisplay = true;
                    context.Set<PersonalLink>().Add(link);

                    if (context.SaveChanges() > 0)
                    {
                        return true;
                    }
                }
                return false;
            }
        }

        public bool RemovePersonalLink(PersonalPackage package, Guid linkId)
        {
            using (WorkSpaceContext context = _factory.Get())
            {
                PersonalLink pLink = context.Set<PersonalLink>()
                    .Where(p => p.LinkId == linkId && p.PackageId == package.Id)
                    .FirstOrDefault();
                if (pLink != null)
                {
                    context.Entry(pLink).State = System.Data.Entity.EntityState.Deleted;

                    if (context.SaveChanges() > 0)
                    {
                        return true;
                    }
                }
                return false;
            }
        }

        public bool ClearPersonalLinks(PersonalPackage package)
        {
            using (WorkSpaceContext context = _factory.Get())
            {
                List<PersonalLink> links = context.Set<PersonalLink>()
                    .Where(p => p.PackageId == package.Id).ToList();

                foreach (PersonalLink link in links)
                {
                    context.Entry(link).State = System.Data.Entity.EntityState.Deleted;
                }

                if (context.SaveChanges() > 0)
                {
                    return true;
                }
                return false;
            }
        }

        public PersonalPackage FindPersonalPackage(Guid packageId)
        {
            using (WorkSpaceContext context = _factory.Get())
            {
                return context.Set<PersonalPackage>()
                    .Where(p => p.Id == packageId)
                    .SingleOrDefault();
            }
        }

        public List<PersonalPackage> FindPersonalPackages(Guid categoryId, string account)
        {
            using (WorkSpaceContext context = _factory.Get())
            {
                return context.Set<PersonalPackage>()
                    .Where(p=>p.Account == account && p.CategoryId == categoryId)
                    .OrderBy(p => p.OrderIndex)
                    .ToList();
            }
        }

        public List<PersonalLink> FindPersonalLinks(Guid packageId, string account)
        {
            using (WorkSpaceContext context = _factory.Get())
            {
                return context.Set<PersonalLink>()
                    .Include("Link")
                    .Where(p => p.Account == account && p.PackageId == packageId)
                    .OrderBy(p => p.OrderIndex)
                    .ToList();
            }
        }

        /// <summary>
        /// 获取用户可以使用的类别
        /// </summary>
        /// <param name="account"></param>
        /// <returns></returns>
        public List<Category> FindPersonalCategories(string account)
        {
            List<Category> categories = new List<Category>();

            OrgMember position = _coreService.FindMajorPosition(account);

            List<Org> parents = _coreService.FindParentOrgs(position.OrgId, Guid.Empty);

            if (parents == null || parents.Count == 0)
            {
                return categories;
            }

            using (WorkSpaceContext context = _factory.Get())
            {
                StringBuilder sql = new StringBuilder();
                sql.Append(@"select distinct wc.* from WSCategory as wc 
    join wslink as wl on wc.Id = wl.CategoryId
	join __User as u on u.Account = wl.Account
	join __orgmember as om on om.UserId = u.Id
where om.Orgid='");

                for (int index = 0; index < parents.Count; index++)
                {
                    if (index == 0)
                    {
                        sql.Append(parents[index].Id.ToString("D"));
                    }
                    else
                    {
                        sql.AppendFormat(@",{0}", parents[index].Id.ToString("D"));
                    }
                }
                sql.Append(@"' and wl.isEnable=1");

                List<Category> list = context.Set<Category>()
                    .SqlQuery(sql.ToString()).ToList();

                categories.AddRange(list);

                categories.AddRange(context.Set<Category>().Where(p => p.Account == account).ToList());

                return categories;
            }
        }
        #region icon

        public bool SaveIcon(IconData icon)
        {
            using (WorkSpaceContext context = _factory.Get())
            {
                if (context.Set<IconData>()
                    .Where(p => p.Id == icon.Id)
                    .Select(p => p.Id)
                    .FirstOrDefault() == default(Guid))
                {
                    context.Set<IconData>().Add(icon);
                }
                else
                {
                    context.Entry(icon).State = System.Data.Entity.EntityState.Modified;
                }

                if (context.SaveChanges() > 0)
                {
                    return true;
                }
                return false;
            }
        }
        
        public IconData FindIcon(Guid id)
        {
            using (WorkSpaceContext context = _factory.Get())
            {
                return context.Set<IconData>()
                    .Where(p => p.Id == id)
                    .FirstOrDefault();
            }
        }
        
        public List<IconData> FindIcons()
        {
            using (WorkSpaceContext context = _factory.Get())
            {
                return context.Set<IconData>()
                    .Select(p => new IconData{ Id=p.Id, Caption = p.Caption })
                    .ToList<IconData>();
            }
        }
        #endregion
    }
}
